package com.ncmmall.querychannel;

import com.mysema.query.types.OrderSpecifier;
import com.mysema.query.types.Predicate;

import java.util.List;
import java.util.Map;

/**
 * @author linxs
 */
public interface QueryRepository {

    <T> T findOne(Class<T> clazz, Object primaryKey);

    <T> List<T> findAll(Predicate predicate, Class<T> clazz);

    <T> List<T> findAll(Predicate predicate, OrderSpecifier<?>[] orders, Class<T> clazz);

    <T> T findOne(Predicate predicate, Class<T> clazz);

    Object findOne(String sql);

    <T> T findOne(String sql, Class<T> clazz);

    <T> T findFirst(String sql, Map<String, Object> params, Class<T> clazz);

    <T> T selectOneDTO(String sql, Map<String, Object> params, JpaQueryUnwrap unwrap);

    Map<String, Object> selectOneMap(String sql, Map<String, Object> params, JpaQueryUnwrap unwrap);

    /**
     * @param sql         原生sql语句
     * @param pageRequest
     * @param clazz       必须是Entity实体对象
     * @return 返回 Entity对象列表
     */
    <T> List<T> queryLimitEntity(String sql, QueryPageRequest pageRequest, Class<T> clazz);

    /**
     * 返回带有分页的结果集
     *
     * @param sql         原生sql语句
     * @param pageRequest
     * @param clazz       必须是Entity实体对象
     * @return
     */
    <T> QueryPage<T> queryPageEntity(String sql, QueryPageRequest pageRequest, Class<T> clazz);

    /**
     * @param sql         原生sql语句
     * @param pageRequest
     * @param unwrap      用于把查询结果转换成定义的对象转化器
     * @return
     */
    <T> QueryPage<T> selectPageDTO(String sql, QueryPageRequest pageRequest, JpaQueryUnwrap unwrap);

    /**
     * @param sql         原生sql语句
     * @param pageRequest
     * @param unwrap      用于把查询结果转换成定义的bean对象转化器
     * @return
     */
    <T> List<T> selectLimitDTO(String sql, QueryPageRequest pageRequest, JpaQueryUnwrap unwrap);


    <T> List<T> selectAllDTO(String sql, Map<String, Object> params, JpaQueryUnwrap unwrap);

    List<Map<String, Object>> selectAllMap(String sql, Map<String, Object> params, JpaQueryUnwrap unwrap);

    int selectCount(String sql, Map<String, Object> params);

    double selectAvg(String sql, Map<String, Object> params);

    <T> List<T> queryAllEntity(String sql, Map<String, Object> params, Class<T> clazz);

    <T> T queryOneEntity(String sql, Map<String, Object> params, Class<T> clazz);

    /**
     * @param queryString
     * @param params
     * @return
     */
    <T> T findOne(String queryString, Map<String, Object> params, Class<T> clazz);

    /**
     * @param queryString
     * @param params
     * @param clazz
     * @return
     */
    <T> List<T> findAll(String queryString, Map<String, Object> params, Class<T> clazz);

    /**
     * @param queryString
     * @param pageRequest
     * @param clazz
     * @return
     */
    <T> List<T> findLimit(String queryString, QueryPageRequest pageRequest, Class<T> clazz);

    /**
     * @param queryString
     * @param pageRequest
     * @param clazz
     * @param <T>
     * @return
     */
    <T> QueryPage<T> findPage(String queryString, QueryPageRequest pageRequest, Class<T> clazz);

    <T> Long findCount(Predicate predicate, Class<T> clazz);

    <T> List<T> findAll(int limit, int count, String queryString, Map<String, Object> params, Class<T> clazz);

    Double selectSum(String sql, Map<String, Object> params);
}
